<template>
  <FaLayout v-loading="loading" class="page" :right="240" :left="240">
    <AppHeader slot="header">
      <ElButton type="primary" @click="submit">提交</ElButton>
    </AppHeader>

    <FaPanel slot="left" title="控件填写" style="height: 100%">
      <FaWidgetFill ref="widgetFill" :viewer="viewer">
        <template #start="{ total, required, verified }">
          <div class="fill-counter">
            <div>总数量： {{ total }}</div>
            <div>必填： {{ required }}</div>
            <div>通过校验： {{ verified }}</div>
          </div>
        </template>
      </FaWidgetFill>

      <footer v-if="widgetFill" slot="footer" class="widget-fill-ft">
        <ElButton @click="() => widgetFill?.clearValidate()">清除校验</ElButton>
        <ElButton type="primary" @click="() =>widgetFill?.validate()">校验</ElButton>
      </footer>
    </FaPanel>

    <FaContract
      ref="viewer"
      :docs="docs"
      :doc-index.sync="docIndex"
      :page-src="getPageImg"
      widget
      :widgets="widgets"
      :attachment-upload="attachmentUpload"
      :image-upload="imageUpload"
      :image-src="imageSrc"
    />

    <FaThumbs slot="right" :viewer="viewer" :docs="docs" :doc-index.sync="docIndex" />
  </FaLayout>
</template>

<script lang="ts">
import { defineComponent, onMounted, reactive, Ref, ref, toRefs } from 'vue'
import { WidgetMode, ActorData, Widget, DocData, Viewer, createId, FaWidgetFill, RawField } from 'fdd-contract'
import AppHeader from '../components/AppHeader.vue'
import { filled, filling } from '../mocks/fillWidgets'
import { getDetail, getPageImg } from '../utils/mock'
import { alertWidgetsRaw, mockAjax } from '../utils'

/** 合同填写 */
export default defineComponent({
  name: 'ContractSign',
  components: { AppHeader },

  setup() {
    /** 合同控件 */
    const viewer = ref(null) as Ref<Viewer | null>

    /** 控件表单填写 */
    const widgetFill = ref(null) as Ref<InstanceType<typeof FaWidgetFill> | null>

    /** 详情数据 */
    const detail = reactive({
      docs: [] as DocData[],
      actors: [] as ActorData[],
      widgets: [] as Widget[]
    })

    /** 加载中 */
    const loading = ref(false)

    /** 当前文档索引 */
    const docIndex = ref(0)

    /** 详情加载 */
    async function load() {
      try {
        loading.value = true

        const { docs, actors, signs } = await getDetail()

        Object.assign(detail, { docs, actors, signs })

        /** 已填写的控件 */
        const filledWidgets = filled.map(item =>
          /** 从后端 JSON 数据创建控件 */
          Widget.createRawWidget(item as RawField, {
            // 已填写模式为完成
            mode: WidgetMode.DONE,
            docId: docs[0].id,
            actor: actors[2]
          })
        )

        /** 填写中的控件 */
        const fillingWidgets = filling.map(item =>
          /** 从后端 JSON 数据创建控件 */
          Widget.createRawWidget(item as RawField, {
            // 填写中模式为使用
            mode: WidgetMode.USE,
            docId: docs[0].id,
            actor: actors[0]
          })
        )

        detail.widgets = [...filledWidgets, ...fillingWidgets]
      } finally {
        loading.value = false
      }
    }

    onMounted(load)

    return {
      ...toRefs(detail),

      /** 合同控件 */
      viewer,

      /** 控件表单填写 */
      widgetFill,

      /** 加载中 */
      loading,

      /** 当前文档索引 */
      docIndex,

      /** 获取文档页面图片地址 */
      getPageImg,

      /** 附件上传 */
      attachmentUpload(file: File) {
        return mockAjax(() => ({
          id: createId(),
          fileName: file.name
        }))
      },

      /** 图片上传 */
      async imageUpload(file: File) {
        return mockAjax(() => ({
          // 会作为控件 value 存储
          id: URL.createObjectURL(file),
          fileName: file.name
        }))
      },

      /** 图片地址 */
      imageSrc(widget: Widget) {
        return widget.value
      },

      /** 提交 */
      async submit() {
        await viewer.value?.validate()

        alertWidgetsRaw(detail.widgets)
      }
    }
  }
})
</script>

<style lang="scss" scoped>
.widget-fill-ft {
  padding: 8px 16px;
  text-align: right;
  border-top: $border-solid;
}

.fill-counter {
  padding: 8px 16px;
  font-size: 12px;
}
</style>
